package com.example.gobang.controller;

import com.example.gobang.constant.Constants;
import com.example.gobang.model.Result;
import com.example.gobang.model.UserInfo;
import com.example.gobang.model.MatchRequest;
import com.example.gobang.service.MatchService;
import com.example.gobang.manager.OnlineUserManager;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

@Component
@Slf4j
public class MatchController extends TextWebSocketHandler {
    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private OnlineUserManager onlineUserManager;

    @Autowired
    private MatchService matchService;
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 连接建立之后
        // 获取用户信息
        UserInfo userInfo = (UserInfo) session.getAttributes().get(Constants.USER_INFO);
        if(userInfo == null) {
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(Result.noLogin())));
            return;
        }

        // 判断用户是否已经登录过了（防止用户多开）
        if(onlineUserManager.getFromHall(userInfo.getUserId()) != null || onlineUserManager.getFromRoom(userInfo.getUserId()) != null) {
            // 用户已经登录过
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(Result.repeatConnection())));
            log.info("已禁止玩家 {} 多开游戏", userInfo.getUserName());
            System.out.println(onlineUserManager.getFromHall(userInfo.getUserId()) != null);
            System.out.println(onlineUserManager.getFromRoom(userInfo.getUserId()) != null);
            return;
        }

        // 拿到用户信息后，将用户设置为在线状态
        onlineUserManager.enterGameHall(userInfo.getUserId(), session);
        log.info("玩家 {} 进入游戏大厅", userInfo.getUserName());

    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 开始处理匹配请求和停止匹配请求
        UserInfo userInfo = (UserInfo) session.getAttributes().get(Constants.USER_INFO);
        // 处理用户尚未登录的情况
        if(userInfo == null) {
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(Result.noLogin())));
            return;
        }
        // 获取客户端发送的数据
        String payload = message.getPayload();
        // 将 JSON 字符串转换成 Java 对象
        MatchRequest matchRequest = objectMapper.readValue(payload, MatchRequest.class);
        if (matchRequest.getMessage().equals(Constants.START_MATCH)) {
            // 开始匹配，将其放到匹配队列中
            matchService.add(userInfo);
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(Result.success("开始匹配", Constants.START_MATCH))));
        } else if (matchRequest.getMessage().equals(Constants.STOP_MATCH)) {
            // 结束匹配，将其从匹配队列中移除
            matchService.remove(userInfo);
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(Result.success("结束匹配", Constants.STOP_MATCH))));
        } else {
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(Result.fail("错误的匹配信息！"))));
        }
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        // 当前登录玩家
        UserInfo userInfo = (UserInfo) session.getAttributes().get(Constants.USER_INFO);
        // 当前玩家是否登录
        if(userInfo == null) {
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(Result.noLogin())));
        }
        // 游戏大厅中存储的玩家信息
        WebSocketSession onlineSession = onlineUserManager.getFromHall(userInfo.getUserId());
        // 判断是否是在线玩家下线（避免关闭多开时将玩家信息错误删除）
        if(session == onlineSession) {
            // 玩家下线
            // 将其从匹配队列中移除
            matchService.remove(userInfo);
        }
        // 玩家正在匹配中，webSocket连接断开，移除匹配队列
        // 将其从游戏大厅中移除
        onlineUserManager.exitGameHall(userInfo.getUserId());
        log.info("玩家 {} 从游戏大厅退出", userInfo.getUserName());
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        // 当前登录玩家
        UserInfo userInfo = (UserInfo) session.getAttributes().get(Constants.USER_INFO);
        // 当前玩家是否登录
        if(userInfo == null) {
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(Result.noLogin())));
        }
        // 游戏大厅中存储的玩家信息
        WebSocketSession onlineSession = onlineUserManager.getFromHall(userInfo.getUserId());
        // 判断是否是在线玩家下线（避免关闭多开时将玩家信息错误删除）
        if(session == onlineSession) {
            // 玩家下线
            // 将其从匹配队列中移除
            matchService.remove(userInfo);
        }
        // 玩家正在匹配中，webSocket连接断开，移除匹配队列
        // 将其从游戏大厅中移除
        onlineUserManager.exitGameHall(userInfo.getUserId());
        log.info("玩家 {} 从游戏大厅退出", userInfo.getUserName());
    }
}
